package com.qzsoft.zhjd.monitoring.utils;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qzsoft.zhjd.monitoring.config.ZLMMediaConfig;
import com.qzsoft.zhjd.monitoring.config.ZLMServerConfig;
import com.qzsoft.zhjd.monitoring.modules.videomonitor.entity.VideoMonitorEntity;

import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName ZLMRestfulUtils
 * @Description MediaServer HTTP API 工具类
 * @author linhuawei
 * @since 2022-03-22
 */
@Slf4j
@Component
public class ZLMRestfulUtils {

    @Autowired
    private ZLMMediaConfig zlmMediaConfig;

    /**
     * @Title addStreamProxy
     * @Description 添加推流代理
     * @param entity 视频监控对象
     * @return 返回结果
     */
    public Boolean addStreamProxy(VideoMonitorEntity entity) {
        // 根据监控类型不同,调用不同的接口
        JSONObject result = null;
        if ("default".equals(entity.getType())) {
            Map<String, Object> params = new HashMap<>();
            params.put("vhost", "__defaultVhost__");
            params.put("app", entity.getApp());
            params.put("stream", entity.getStream());
            params.put("url", entity.getUrl());
            params.put("enable_hls", entity.getEnableHls());// 是否转换成hls协议
            params.put("enable_mp4", entity.getEnableMp4());// 是否允许mp4录制
            params.put("enable_rtsp", 0);// 是否转rtsp协议
            params.put("enable_rtmp", 0);// 是否转rtmp/flv协议
            params.put("enable_ts", 0);// 是否转http-ts/ws-ts协议
            params.put("enable_fmp4", 0);// 是否转http-fmp4/ws-fmp4协议
            params.put("enable_audio", 0);// 转协议时是否开启音频
            params.put("add_mute_audio", 0);// 转协议时，无音频是否添加静音aac音频
            params.put("rtp_type", 1);// rtsp拉流时，拉流方式，0：tcp，1：udp，2：组播
            result = sendPost("addStreamProxy", params);
        } else if ("ffmpeg".equals(entity.getType())) {
            Map<String, Object> params = new HashMap<>();
            params.put("src_url", entity.getSrcUrl());
            params.put("dst_url", entity.getDstUrl());
            params.put("timeout_ms", entity.getTimeoutMs());
            result = sendPost("addFFmpegSource", params);
        } else {
            log.error("未知的视频监控类型:type = {}", entity.getType());
        }

        return null != result && "0".equals(result.getString("code"));
    }

    /**
     * @Title getServerConfig
     * @Description 获取服务器配置信息
     * @return 服务器配置信息
     */
    public ZLMServerConfig getServerConfig() {
        Map<String, Object> params = new HashMap<String, Object>();
        JSONObject result = sendPost("getServerConfig", params);
        ZLMServerConfig data = null;
        if (null != result) {
            if ("0".equals(result.getString("code"))) {
                JSONArray array = result.getJSONArray("data");
                if (null == array || 0 == array.size()) {
                    log.error("连接ZLM服务getServerConfig失败：result = {}", result);
                } else {
                    data = JSON.toJavaObject(array.getJSONObject(0), ZLMServerConfig.class);
                }
            } else {
                log.error("连接ZLM服务getServerConfig失败：result = {}", result);
            }
        }
        return data;
    }

    /**
     * @Title closeStreamsByForce
     * @Description 关闭推流代理(有人在观看也关闭)
     * @param app
     * @param stream
     * @return
     */
    public boolean closeStreamsByForce(String app, String stream) {
        Map<String, Object> params = new HashMap<>();
        params.put("vhost", "__defaultVhost__");
        params.put("app", app);
        params.put("stream", stream);
        params.put("force", 1);
        JSONObject result = sendPost("close_streams", params);
        return null != result && "0".equals(result.getString("code"));
    }

    /**
     * @Title getMediaList
     * @Description 获取媒体列表
     * @param app
     * @param stream
     * @return
     */
    public JSONArray getMediaList(String app, String stream) {
        Map<String, Object> params = new HashMap<>();
        params.put("vhost", "__defaultVhost__");
        params.put("app", app);
        params.put("stream", stream);
        JSONObject result = sendPost("getMediaList", params);
        if (null != result && "0".equals(result.getString("code"))) {
            return result.getJSONArray("data");
        }
        return null;
    }

    /**
     * @Title sendPost
     * @Description 发送post请求
     * @param api    请求接口
     * @param params 请求参数
     * @return 请求结果
     */
    private JSONObject sendPost(String api, Map<String, Object> params) {
        // 调用api接口
        String url = String.format("http://%s:%s/index/api/%s", zlmMediaConfig.getIp(), zlmMediaConfig.getHttpPort(),
                api);
        JSONObject result = null;
        try {
            params.put("secret", zlmMediaConfig.getSecret());
            String text = HttpUtil.post(url, params);
            if (null == text) {
                log.error("连接ZLM返回结果解析失败：url={}, result = {}", url, text);
            } else {
                try {
                    result = JSONObject.parseObject(text);
                } catch (Exception e) {
                    log.error("连接ZLM返回结果解析失败：url={}, result = {}", url, text);
                    result = null;
                }
            }
        } catch (Exception e) {
            result = null;
            log.error("连接ZLM失败:url = {}, ex = {}", url, e.getMessage());
            log.info("请检查media配置并确认ZLM已启动...");
        }

        // 返回结果
        return result;
    }
}
